﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Cache;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;



namespace YinLongTool.Net.Http
{
	public class HttpHelper
	{
		private string acceptLanguage = "zh-cn,zh;q=0.5";

		private string acceptEncoding = "gzip, deflate";

		private string acceptCharset = "GB2312,utf-8;q=0.7,*;q=0.7";

		private string accept = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";

		private string contentType = "application/x-www-form-urlencoded";

		private string lastrequesturl = "";

		private string redirectLocation = "";

		private WebHeaderCollection _webHeaderCollection;

		private static HttpHelper _default;

		public string LastStatusCodeCode
		{
			get;
			private set;
		}

		public WebHeaderCollection ResponseHeader => _webHeaderCollection;

		public string Lastrequesturl => lastrequesturl;

		public string RedirectLocation => redirectLocation;

		public CookieContainer Cookies
		{
			get;
			set;
		}

		public bool AutoCharSet
		{
			get;
			set;
		}

		public System.Text.Encoding Charset
		{
			get;
			set;
		}

		public string UserAgent
		{
			get;
			set;
		}

		public IWebProxy Proxy
		{
			get;
			set;
		}

		public static HttpHelper Default
		{
			get
			{
				_default = new HttpHelper();
				return _default;
			}
		}

		public HttpHelper()
		{
			AutoCharSet = true;
			Charset = System.Text.Encoding.UTF8;
			UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
		}

		public string Get(HttpHeader header)
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			string text = "";
			int num = 0;
			do
			{
				try
				{
					httpWebRequest = (HttpWebRequest)WebRequest.Create(header.Url);
					httpWebRequest.Method = "GET";
					SetRequestProperty(httpWebRequest, header);
					try
					{
						httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
					}
					catch (WebException ex)
					{
						httpWebResponse = (ex.Response as HttpWebResponse);
					}
					lastrequesturl = httpWebRequest.Address.ToString();
					LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
					Stream stream = httpWebResponse.GetResponseStream();
					if (AutoCharSet)
					{
						string characterSet = httpWebResponse.CharacterSet;
						if (characterSet != null && characterSet == "ISO-8859-1")
						{
							Charset = System.Text.Encoding.GetEncoding("gb2312");
						}
						else
						{
							Charset = System.Text.Encoding.GetEncoding(httpWebResponse.CharacterSet);
						}
					}
					if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
					{
						stream = new GZipStream(stream, CompressionMode.Decompress);
					}
					if (httpWebResponse.ContentEncoding.ToLower().Contains("deflate"))
					{
						stream = new DeflateStream(stream, CompressionMode.Decompress);
					}
					streamReader = new StreamReader(stream, Charset);
					text = streamReader.ReadToEnd();
					if (header.HtmlDecode)
					{
						text = CharSetHelper.HtmlDecode(text);
					}
					httpWebRequest.Abort();
					_webHeaderCollection = httpWebResponse.Headers;
					lastrequesturl = httpWebRequest.Address.ToString();
					LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
					redirectLocation = httpWebResponse.Headers["Location"];
				}
				catch (Exception)
				{
					LastStatusCodeCode = "500";
				}
				finally
				{
					if (httpWebResponse != null)
					{
						httpWebResponse.Close();
						httpWebResponse = null;
					}
					if (streamReader != null)
					{
						streamReader.Close();
						streamReader = null;
					}
					if (httpWebRequest != null)
					{
						httpWebRequest = null;
					}
				}
			}
			while (string.IsNullOrEmpty(text) && ++num < header.RetryCount);
			return text;
		}

		public string Post(HttpHeader header)
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			Stream stream = null;
			string text = "";
			int num = 0;
			do
			{
				try
				{
					httpWebRequest = (HttpWebRequest)WebRequest.Create(header.Url);
					httpWebRequest.Method = "POST";
					SetRequestProperty(httpWebRequest, header);
					httpWebRequest.ContentType = contentType;
					if (!string.IsNullOrEmpty(header.ContentType))
					{
						httpWebRequest.ContentType = header.ContentType;
					}
					byte[] bytes = header.PostDataEncoding.GetBytes(header.PostData);
					httpWebRequest.ContentLength = bytes.Length;
					stream = httpWebRequest.GetRequestStream();
					stream.Write(bytes, 0, bytes.Length);
					stream.Close();
					try
					{
						httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
					}
					catch (WebException ex)
					{
						httpWebResponse = (ex.Response as HttpWebResponse);
					}
					lastrequesturl = httpWebRequest.Address.ToString();
					LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
					redirectLocation = httpWebResponse.Headers["Location"];
					if (AutoCharSet)
					{
						Charset = System.Text.Encoding.GetEncoding(httpWebResponse.CharacterSet);
					}
					Stream stream2 = httpWebResponse.GetResponseStream();
					if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
					{
						stream2 = new GZipStream(stream2, CompressionMode.Decompress);
					}
					streamReader = new StreamReader(stream2, Charset);
					text = streamReader.ReadToEnd();
					if (header.HtmlDecode)
					{
						text = CharSetHelper.HtmlDecode(text);
					}
					_webHeaderCollection = httpWebResponse.Headers;
				}
				catch (Exception)
				{
					LastStatusCodeCode = "500";
				}
				finally
				{
					if (httpWebResponse != null)
					{
						httpWebResponse.Close();
						httpWebResponse = null;
					}
					if (streamReader != null)
					{
						streamReader.Close();
						streamReader = null;
					}
					if (httpWebRequest != null)
					{
						httpWebRequest = null;
					}
				}
			}
			while (string.IsNullOrEmpty(text) && ++num < header.RetryCount);
			return text;
		}

		public string Put(HttpHeader header)
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			Stream stream = null;
			string text = "";
			int num = 0;
			do
			{
				try
				{
					httpWebRequest = (HttpWebRequest)WebRequest.Create(header.Url);
					httpWebRequest.Method = "PUT";
					SetRequestProperty(httpWebRequest, header);
					httpWebRequest.ContentType = contentType;
					if (!string.IsNullOrEmpty(header.ContentType))
					{
						httpWebRequest.ContentType = header.ContentType;
					}
					byte[] bytes = header.PostDataEncoding.GetBytes(header.PostData);
					httpWebRequest.ContentLength = bytes.Length;
					stream = httpWebRequest.GetRequestStream();
					stream.Write(bytes, 0, bytes.Length);
					stream.Close();
					try
					{
						httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
					}
					catch (WebException ex)
					{
						httpWebResponse = (ex.Response as HttpWebResponse);
					}
					lastrequesturl = httpWebRequest.Address.ToString();
					LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
					redirectLocation = httpWebResponse.Headers["Location"];
					if (AutoCharSet)
					{
						Charset = System.Text.Encoding.GetEncoding(httpWebResponse.CharacterSet);
					}
					Stream stream2 = httpWebResponse.GetResponseStream();
					if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
					{
						stream2 = new GZipStream(stream2, CompressionMode.Decompress);
					}
					streamReader = new StreamReader(stream2, Charset);
					text = streamReader.ReadToEnd();
					if (header.HtmlDecode)
					{
						text = CharSetHelper.HtmlDecode(text);
					}
					_webHeaderCollection = httpWebResponse.Headers;
				}
				catch (Exception)
				{
					LastStatusCodeCode = "500";
				}
				finally
				{
					if (httpWebResponse != null)
					{
						httpWebResponse.Close();
						httpWebResponse = null;
					}
					if (streamReader != null)
					{
						streamReader.Close();
						streamReader = null;
					}
					if (httpWebRequest != null)
					{
						httpWebRequest = null;
					}
				}
			}
			while (string.IsNullOrEmpty(text) && ++num < header.RetryCount);
			return text;
		}

		public string Post(HttpHeader header, MsMultiPartFormData mformData)
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			Stream stream = null;
			string text = "";
			int num = 0;
			do
			{
				try
				{
					httpWebRequest = (HttpWebRequest)WebRequest.Create(header.Url);
					httpWebRequest.Method = "POST";
					SetRequestProperty(httpWebRequest, header);
					httpWebRequest.ContentType = "multipart/form-data; boundary=" + mformData.Boundary;
					byte[] array = mformData.GetFormData().ToArray();
					httpWebRequest.ContentLength = array.Length;
					stream = httpWebRequest.GetRequestStream();
					stream.Write(array, 0, array.Length);
					stream.Close();
					try
					{
						httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
					}
					catch (WebException ex)
					{
						httpWebResponse = (ex.Response as HttpWebResponse);
					}
					LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
					redirectLocation = httpWebResponse.Headers["Location"];
					if (AutoCharSet)
					{
						Charset = System.Text.Encoding.GetEncoding(httpWebResponse.CharacterSet);
					}
					Stream stream2 = httpWebResponse.GetResponseStream();
					if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
					{
						stream2 = new GZipStream(stream2, CompressionMode.Decompress);
					}
					streamReader = new StreamReader(stream2, Charset);
					text = streamReader.ReadToEnd();
					if (header.HtmlDecode)
					{
						text = CharSetHelper.HtmlDecode(text);
					}
					_webHeaderCollection = httpWebResponse.Headers;
				}
				catch (Exception)
				{
					LastStatusCodeCode = "500";
				}
				finally
				{
					if (httpWebResponse != null)
					{
						httpWebResponse.Close();
						httpWebResponse = null;
					}
					if (streamReader != null)
					{
						streamReader.Close();
						streamReader = null;
					}
					if (httpWebRequest != null)
					{
						httpWebRequest = null;
					}
				}
			}
			while (string.IsNullOrEmpty(text) && ++num < header.RetryCount);
			return text;
		}

		private void SetRequestProperty(HttpWebRequest request, HttpHeader header)
		{
			ServicePoint servicePoint = request.ServicePoint;
			servicePoint.ConnectionLimit = 1000;
			ServicePointManager.DnsRefreshTimeout = header.Timeout;
			request.Timeout = header.Timeout;
			request.AllowAutoRedirect = header.AllowAutoRedirect;
			if (!string.IsNullOrEmpty(header.UserAgent))
			{
				UserAgent = header.UserAgent;
			}
			request.UserAgent = UserAgent;
			request.Accept = accept;
			if (!string.IsNullOrEmpty(header.Accept))
			{
				request.Accept = header.Accept;
			}
			request.KeepAlive = header.KeepAlive;
			if (header.KeepAlive)
			{
				PropertyInfo property = request.ServicePoint.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
				property.SetValue(request.ServicePoint, (byte)0, null);
			}
			if (header.KeepAlive && header.KeepAliveValue > 0)
			{
				request.Headers[HttpRequestHeader.KeepAlive] = header.KeepAliveValue.ToString();
			}
			request.Referer = header.ReferUrl;
			request.CookieContainer = Cookies;
			if (!string.IsNullOrEmpty(header.CustomCooikeString))
			{
				request.Headers["Cookie"] = header.CustomCooikeString;
			}
			request.ReadWriteTimeout = header.ReadWriteTimeout;
			ServicePointManager.Expect100Continue = false;
			request.ServicePoint.Expect100Continue = false;
			if (header.Url.ToLower().StartsWith("https"))
			{
				ServicePointManager.ServerCertificateValidationCallback = ((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true);
				request.ProtocolVersion = HttpVersion.Version10;
				request.Credentials = CredentialCache.DefaultCredentials;
			}
			request.Headers[HttpRequestHeader.AcceptCharset] = acceptCharset;
			if (!string.IsNullOrEmpty(header.AcceptCharset))
			{
				request.Headers[HttpRequestHeader.AcceptCharset] = header.AcceptCharset;
			}
			request.Headers[HttpRequestHeader.AcceptEncoding] = acceptEncoding;
			if (!string.IsNullOrEmpty(header.AcceptEncoding))
			{
				request.Headers[HttpRequestHeader.AcceptEncoding] = header.AcceptEncoding;
			}
			request.Headers[HttpRequestHeader.AcceptLanguage] = acceptLanguage;
			if (!string.IsNullOrEmpty(header.AcceptLanguage))
			{
				request.Headers[HttpRequestHeader.AcceptLanguage] = header.AcceptLanguage;
			}
			request.Headers.Set("Pragma", "no-cache");
			if (Proxy != null)
			{
				request.Proxy = Proxy;
				Proxy.Credentials = CredentialCache.DefaultCredentials;
				request.UseDefaultCredentials = true;
			}
			foreach (KeyValuePair<string, string> item in header.CustomHeader)
			{
				request.Headers.Add(item.Key, item.Value);
			}
			HttpRequestCachePolicy httpRequestCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
		}

		public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
		{
			return true;
		}

		public void DownFile(string url, string fileName)
		{
			try
			{
				WebClient webClient = new WebClient();
				webClient.DownloadFile(url, fileName);
			}
			catch (Exception)
			{
			}
		}

		public void DownImage(string url, string fileName, string refUrl = "")
		{
			DownImage(url, fileName, refUrl, ImageFormat.Jpeg);
		}

		public void DownImage(string url, string fileName, string refUrl = "", ImageFormat imageFormat = null)
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			string text = "";
			HttpHeader httpHeader = new HttpHeader();
			httpHeader.Url = url;
			httpHeader.KeepAlive = true;
			httpHeader.ReferUrl = refUrl;
			HttpHeader httpHeader2 = httpHeader;
			try
			{
				httpWebRequest = (HttpWebRequest)WebRequest.Create(httpHeader2.Url);
				httpWebRequest.Method = "GET";
				SetRequestProperty(httpWebRequest, httpHeader2);
				httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
				LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
				Stream stream = httpWebResponse.GetResponseStream();
				if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
				{
					stream = new GZipStream(stream, CompressionMode.Decompress);
				}
				if (httpWebResponse.ContentEncoding.ToLower().Contains("deflate"))
				{
					stream = new DeflateStream(stream, CompressionMode.Decompress);
				}
				Image image = Image.FromStream(stream);
				image.Save(fileName, imageFormat);
			}
			catch (Exception)
			{
				LastStatusCodeCode = "500";
			}
			finally
			{
				if (httpWebResponse != null)
				{
					httpWebResponse.Close();
					httpWebResponse = null;
				}
				if (streamReader != null)
				{
					streamReader.Close();
					streamReader = null;
				}
				if (httpWebRequest != null)
				{
					httpWebRequest = null;
				}
			}
		}

		private void CopyStream(Stream input, Stream output)
		{
			byte[] array = new byte[8192];
			int count;
			while ((count = input.Read(array, 0, array.Length)) > 0)
			{
				output.Write(array, 0, count);
			}
		}

		public void DownFileWithCooike(string url, string fileName, string refUrl = "")
		{
			HttpWebRequest httpWebRequest = null;
			HttpWebResponse httpWebResponse = null;
			StreamReader streamReader = null;
			string text = "";
			HttpHeader httpHeader = new HttpHeader();
			httpHeader.Url = url;
			httpHeader.KeepAlive = true;
			httpHeader.ReferUrl = refUrl;
			HttpHeader httpHeader2 = httpHeader;
			try
			{
				httpWebRequest = (HttpWebRequest)WebRequest.Create(httpHeader2.Url);
				httpWebRequest.Method = "GET";
				SetRequestProperty(httpWebRequest, httpHeader2);
				httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
				LastStatusCodeCode = Convert.ToInt32(httpWebResponse.StatusCode).ToString();
				Stream responseStream = httpWebResponse.GetResponseStream();
				using (Stream output = File.Create(fileName))
				{
					CopyStream(responseStream, output);
				}
			}
			catch (Exception)
			{
				LastStatusCodeCode = "500";
			}
			finally
			{
				if (httpWebResponse != null)
				{
					httpWebResponse.Close();
					httpWebResponse = null;
				}
				if (streamReader != null)
				{
					streamReader.Close();
					streamReader = null;
				}
				if (httpWebRequest != null)
				{
					httpWebRequest = null;
				}
			}
		}

		public string GetCookieValue(string key)
		{
			if (Cookies == null)
			{
				return "";
			}
			List<Cookie> allCookies = CookieHelper.GetAllCookies(Cookies);
			foreach (Cookie item in allCookies)
			{
				if (item.Name.ToLower() == key.ToLower())
				{
					return item.Value;
				}
			}
			return "";
		}
	}
}
